namespace Gamov.DeleteSdData.Main.Background
{
    using System;
    using System.Collections.Generic;
    using System.IO;
    using System.Linq;
    using System.Threading;
    using System.Threading.Tasks;
    using Gamov.DeleteSdData.Main.Frame.Attributes;
    using Gamov.DeleteSdData.Main.Models.Config;
    using Gamov.DeleteSdData.Main.Services;
    using Microsoft.Extensions.Hosting;
    using Microsoft.Extensions.Logging;
    using Microsoft.Extensions.Options;
    using Spectre.Console;

    [HostService]
    public class InitHostService : BackgroundService
    {
        private readonly ILogger<InitHostService> _logger;
        private readonly AppConfig _appConfig;
        private readonly IServiceProvider _serviceProvider;
        private readonly IFileService _fileService;
        private readonly IDiskService _diskService;

        public InitHostService(
            ILogger<InitHostService> logger,
            IServiceProvider serviceProvider,
            IOptions<AppConfig> testConfig,
            IDiskService diskService,
            IFileService fileService)
        {
            _logger = logger;
            _serviceProvider = serviceProvider;
            _appConfig = testConfig.Value;
            _diskService = diskService;
            _fileService = fileService;
        }

        protected override async Task ExecuteAsync(CancellationToken stoppingToken)
        {

            AnsiConsole.Write(new FigletText("Camera Disk Init").Centered().Color(Color.Red));
            var removableDiskNames = _diskService.GetRemovableDeviceID();
            if (!removableDiskNames.Any())
            {
                AnsiConsole.MarkupLine("[red]No external disk detected. Please insert an SD card and try again.[/]");
                return;
            }

            var isContinue = AnsiConsole.Prompt(new TextPrompt<bool>("Confirm deletion of photos from SD card?")
                                .AddChoice(true)
                                .AddChoice(false)
                                .DefaultValue(true)
                                .WithConverter(choice => choice ? "y" : "n"));

            await AnsiConsole.Status()
                                 .AutoRefresh(true)
                                 .StartAsync("Processing, please wait...", async ctx =>
                                 {
                                     ctx.Spinner(Spinner.Known.Star);
                                     ctx.SpinnerStyle(Style.Parse("green"));
                                     Run(removableDiskNames);
                                 });
            AnsiConsole.MarkupLine($"[green]In the end[/]");
        }

        private void Run(IEnumerable<string> removableDiskNames)
        {
            foreach (var diskName in removableDiskNames)
            {
                var sonyDir = Path.Combine(diskName, "AVF_INFO");
                var limuxDir = Path.Combine(diskName, "DCIM");

                if (Directory.Exists(sonyDir))
                {
                    _fileService.ClearDirectory(sonyDir);
                }
                if (Directory.Exists(limuxDir))
                {
                    _fileService.ClearDirectory(limuxDir);
                }

                _logger.LogInformation($"Start to copy [{_appConfig.AVF_INFO_Path}] -> [{sonyDir}]");
                _fileService.CopyFolder(_appConfig.AVF_INFO_Path, sonyDir);
            }
        }
    }
}
